package io.github.wppli.infrastructure.persistent.repository;

import com.alibaba.fastjson2.JSON;
import io.github.wppli.domain.authenticate.model.entity.UserEntity;
import io.github.wppli.domain.recommond.model.entity.RecommendUserEntity;
import io.github.wppli.domain.task.model.entity.TaskEntity;
import io.github.wppli.domain.user.event.AdjustUserFollowedEvent;
import io.github.wppli.domain.user.model.entity.FollowTaskEntity;
import io.github.wppli.domain.user.model.entity.FollowUserEntity;
import io.github.wppli.domain.user.repository.IUserRepository;
import io.github.wppli.infrastructure.event.EventPublisher;
import io.github.wppli.infrastructure.persistent.dao.ITaskDao;
import io.github.wppli.infrastructure.persistent.dao.IUserDao;
import io.github.wppli.infrastructure.persistent.dao.IUserFollowsDao;
import io.github.wppli.infrastructure.persistent.po.Task;
import io.github.wppli.infrastructure.persistent.po.User;
import io.github.wppli.types.event.BaseEvent;
import lombok.AllArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Repository;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @author li--jiaqiang 2025−03−02
 */
@Repository
@AllArgsConstructor
public class UserRepository implements IUserRepository {

    private static final Logger log = LoggerFactory.getLogger(UserRepository.class);
    private final ITaskDao taskDao;
    private final IUserDao userDao;
    private final ThreadPoolExecutor executor;
    private final EventPublisher eventPublisher;

    @Override
    public void unfollow(FollowTaskEntity taskEntity) {
        // 1. 获取基本信息
        BaseEvent.EventMessage<AdjustUserFollowedEvent.AdjustUserFollowedMessage> message = taskEntity.getMessage();
        AdjustUserFollowedEvent.AdjustUserFollowedMessage adjustUserFollowedMessage = message.getData();
        Long userId = adjustUserFollowedMessage.getUserId();
        Long targetUserId = adjustUserFollowedMessage.getTargetUserId();

        // 插入 task 任务
        Task task = Task.builder()
                .topic(taskEntity.getTopic())
                .messageId(taskEntity.getMessageId())
                .message(JSON.toJSONString(message))
                .userId(taskEntity.getUserId())
                .state(taskEntity.getState().getCode())
                .build();
        taskDao.insertOne(task);

        // 发布事件
        executor.execute(() -> {
            try {
                // 发送消息【在事务外执行，如果失败还有任务补偿】
                eventPublisher.publish(task.getTopic(), task.getMessage());
                // 更新数据库记录，task 任务表
                taskDao.updateTaskSendMessageCompleted(task);
                log.info("调整用户取关记录，发送MQ消息完成 userId: {} targetUserId: {} topic: {}", userId, targetUserId, task.getTopic());
            } catch (Exception e) {
                log.error("调整用户取关记录，发送MQ消息失败 userId: {} targetUserId: {} topic: {}", userId,targetUserId, task.getTopic());
                taskDao.updateTaskSendMessageFail(task);
            }
        });
    }

    @Override
    public void follow(FollowTaskEntity taskEntity) {
        unfollow(taskEntity);
    }

    @Override
    public FollowUserEntity queryFollowUserInfoById(Long followedUserId) {
        User user = userDao.selectById(followedUserId);
        if (user == null) {
            return null;
        }
        return FollowUserEntity.builder()
                .id(user.getId())
                .username(user.getUsername())
                .followCount(user.getFollowCount())
                .followerCount(user.getFollowerCount())
                .favoriteCount(user.getFavoriteCount())
                .avatarUrl(user.getAvatarUrl())
                .build();
    }

    @Override
    public List<RecommendUserEntity> queryByIds(List<Long> userIds) {
        List<User> users = userDao.selectBatchIds(userIds);
        if(users.isEmpty()) {
            return Collections.emptyList();
        }
        List<RecommendUserEntity> recommendUserEntities = new ArrayList<>();
        for (User user : users) {
            RecommendUserEntity recommendUserEntity = RecommendUserEntity.builder()
                        .id(user.getId())
                        .username(user.getUsername())
                        .password(user.getPassword())
                        .email(user.getEmail())
                        .phone(user.getPhone())
                        .lastLoginTimi(user.getLastLoginTimi())
                        .followCount(user.getFollowCount())
                        .followerCount(user.getFollowerCount())
                        .favoriteCount(user.getFavoriteCount())
                        .age(user.getAge())
                        .bio(user.getBio())
                        .avatarUrl(user.getAvatarUrl())
                        .build();
            recommendUserEntities.add(recommendUserEntity);
        }
        return recommendUserEntities;
    }
}